package toepen;


import java.util.LinkedList;
// <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
// #[regen=yes,id=DCE.F1C2C475-485C-C203-AB7B-072466558972]
// </editor-fold> 
/**
 * Iedere spelronde bestaat uit vier speelbeurten. Dit SpeelBeurt object wordt
 * gebruikt voor al die vier speelbeurten. Hiervoor wordt een singleton
 * pattern toegepast
 * @author LucasD
 */
public class SpeelBeurt {

    private static SpeelBeurt newSpeelBeurt;

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.CF686787-FA4E-7437-1345-0A62B3620E55]
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.7C9817A1-8EBB-91CD-5DDD-DF651C17E2E6]
    // </editor-fold>
    /**
     * Beurt 1 tot en met 4
     */
    private int beurtNummer;

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.EC3CB825-756B-CCD0-1AD6-FBB9E0202B02]
    // </editor-fold>
    /**
     * Deelnemer die aan de beurt is
     */
    private Deelnemer deelnemerAanDeBeurt;
    private Antwoord ant;
    private Deelnemer winnaar;
    private Deelnemer deler;
    private Kaart winnendeKaart;
    private LinkedList<Deelnemer> lijstDeelnemer;
    private SpelRonde spelRonde;


    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.9E0AEBA0-9BB6-6B75-7417-8555441936C3]
    // </editor-fold>
    /**
     * Constructor voor Speelbeurt
     * @param spelronde     Spelronde waarvan deze beurtenreeks onderdeel is
     * @param beurtNummer   We moeten altijd weten welke speelbeurt het is
     * @param deelnemerAandeBeurt   deelnemer die nu aan de beurt is
     * @param lijstDeelnemers   lijst met alle deelnemers
     */
    public static void createSpeelBeurt (SpelRonde spelronde, int beurtNummer, Deelnemer deelnemerAandeBeurt, LinkedList<Deelnemer> lijstDeelnemers) {
        newSpeelBeurt = new SpeelBeurt(spelronde, beurtNummer, deelnemerAandeBeurt, lijstDeelnemers);
    }

    /**
     * @return huidige speelbeurt
     */
    public static SpeelBeurt getSpeelBeurt()
    {
        return newSpeelBeurt;
    }

    /**
     * Constructor voor speelbeurt
     * @param spelronde waarin deze beurt valt
     * @param beurtNummer nummer van de beurt
     * @param deelnemerAandeBeurt deelnemer die aan de beurt is
     * @param lijstDeelnemers lijst met deelnemers
     */
    public SpeelBeurt (SpelRonde spelronde, int beurtNummer, Deelnemer deelnemerAandeBeurt, LinkedList<Deelnemer> lijstDeelnemers) {
        winnaar=deelnemerAandeBeurt;
        deler=deelnemerAandeBeurt;
        deelnemerAanDeBeurt=winnaar;
        lijstDeelnemer=lijstDeelnemers;
        deelnemerAanDeBeurt.switchIsAanDeBeurt();
        spelRonde=spelronde;

        // added, beurtNummer is never set when creating a SpeelBeurt
        this.beurtNummer = beurtNummer;
   }

    /**
     * Iedere deelnemer die niet gewonnen heeft krijgt het aantal strafpunten
     * dat ingezet is. Als een deelnemer over de limiet zit wordt deze op
     * inactief gezet
     */
    public void setScores (){
        for (int i = 0; i<lijstDeelnemer.size(); i++) {
            if (lijstDeelnemer.get(i) != getWinnaar()){
                int strafPuntenHuidig = lijstDeelnemer.get(i).getStrafPunten();
                int strafPuntenNieuw = strafPuntenHuidig + lijstDeelnemer.get(i).getInzet();
                lijstDeelnemer.get(i).setStrafPunten(strafPuntenNieuw);
                if (strafPuntenNieuw>=spelRonde.getStrafPuntLimiet()){
                    lijstDeelnemer.get(i).setInactief();
                }
            }
        }
    }


    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,regenBody=yes,id=DCE.A0226D34-D854-BA49-D780-509B3E43A428]
    // </editor-fold>
    /**
     * @return het nummer van de beurt
     */
    public int getBeurtNummer () {
        return beurtNummer;
    }
   

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,regenBody=yes,id=DCE.267A9649-5132-1863-F6A6-33293DAEB6F2]
    // </editor-fold>
    /**
     * @return deelnemer aan de beurt
     */
    public Deelnemer getDeelnemerAanDeBeurt () {
        return deelnemerAanDeBeurt;
    }

    /**
     * Zet de deelnemer die aan de beurt is
     * @param deelnemer aan de beurt
     */
    private void setDeelnemerAanDeBeurt (Deelnemer deelnemer) {
        deelnemerAanDeBeurt=deelnemer;
    }

    /**
     * @return deelnemer die gewonnen heeft of null als nog niemand gewonnen
     * heeft
     */
    public Deelnemer getWinnaar () {
        return winnaar;
    }

    /**
     * Zet de winnaar
     * @param deelnemer die gewonnen heeft
     */
    private void setWinnaar (Deelnemer deelnemer) {
        winnaar=deelnemer;
    }

    /**
     * @return retourneer deelnemer die deelt
     */
    public Deelnemer getDeler () {
        return deler;
    }

    /**
     * Zet de deelnemer die moet gaan delen
     * @param deelnemer die gaat delen
     */
    private void setDeler (Deelnemer deelnemer) {
        deler=deelnemer;
    }

    /**
     * Retourneert de kaart waarmee gewonnen is. Wordt gebruikt voor het kleur
     * bekennen van de volgende spelronde
     * @return winnende kaart
     */
    public Kaart getWinnendeKaart() {
        return winnendeKaart;
    }

    /**
     * Zet de winnende kaart
     * @param kaart die gewonnen heeft
     */
    private void setWinnendeKaart(Kaart kaart) {
        winnendeKaart = kaart;
    }

    /**
     * Controleert wat de actie is van de deelnemer, voert deze uit en
     * retourneert deze vervolgens
     * @param deelnemer waarvan de actie opgehaalt moet worden
     * @return de actie die uitgevoerd is
     */
    public Antwoord getActieDeelnemer (Deelnemer deelnemer){
        // Antwoord antw= deelnemer.getAntwoord();
        if (ant.equals(Antwoord.KAART)){
        }
        else if (ant.equals(Antwoord.KLOPPEN)){
            //SstartKlopronde(deelnemer);
            return ant;
        }
        else if (ant.equals(Antwoord.PASSEN)){
            deelnemer.setStrafPunten(deelnemer.getStrafPunten()+deelnemer.getInzet());
            deelnemer.switchIsAanDeBeurt();
            deelnemer.setInactief();
            setDeelnemerAanDeBeurt(lijstDeelnemer.get(lijstDeelnemer.indexOf(deelnemer)+1));
            lijstDeelnemer.remove(lijstDeelnemer.indexOf(deelnemer));
            return ant;
        }
        else if (ant.equals(Antwoord.OPGEVEN))
        {
            // Het werkelijk verwijderen moet in het spel worden gedaan.
            deelnemer.setStrafPunten(deelnemer.getStrafPunten()+deelnemer.getInzet());
            deelnemer.switchIsAanDeBeurt();
            deelnemer.setInactief();
            setDeelnemerAanDeBeurt(lijstDeelnemer.get(lijstDeelnemer.indexOf(deelnemer)+1));
            lijstDeelnemer.remove(lijstDeelnemer.indexOf(deelnemer));
            return ant;
        }
        return Antwoord.MEEGAAN;
    }

    /**
     * Controleert of de kaart de juiste kleur heeft, en of de waarde hoger is
     * dan de huidige winnende kaart. Als dat zo is dan wordt deze kaart de
     * hoogste kaart
     * @param kaart die gespeeld wordt
     */
   public void checkKaart(Kaart kaart){
        if (kaart.getKleur()==winnendeKaart.getKleur())
        {
            if (kaart.getWaarde().ordinal()>=winnendeKaart.getWaarde().ordinal())
            {
                setWinnendeKaart(kaart);
                setWinnaar(getDeelnemerAanDeBeurt());
            }
        }
    }

    /**
     * Aan het einde van de beurt wordt gekeken of er nog een volgende ronde is,
     * en zo ja de volgende deelnemer de beurt gegeven
     */
    public void eindeBeurt() {
        boolean eindeSpelRonde = false;
        getDeelnemerAanDeBeurt().switchIsAanDeBeurt();
        if (getDeelnemerAanDeBeurt()==lijstDeelnemer.getLast()){
            setDeelnemerAanDeBeurt(lijstDeelnemer.getFirst());
        }
        else{
            setDeelnemerAanDeBeurt(lijstDeelnemer.get(lijstDeelnemer.indexOf(deelnemerAanDeBeurt)+1));
        }
        if (getDeelnemerAanDeBeurt()==getDeler()){
            if (beurtNummer==0){
                this.beurtNummer++;
                setDeler(getWinnaar());
                setDeelnemerAanDeBeurt(getWinnaar());
                setWinnendeKaart(null);
            }
            else {
                //check of het begin van de ronde is
                this.beurtNummer++;
                setDeler(getWinnaar());
                setDeelnemerAanDeBeurt(getWinnaar());
                setWinnendeKaart(null);
            }
            if (getDeler().getSpeelHand().getNietGespeeldeKaarten().size()==0)
            {
                setScores();
                // geefKaartenTerug();
                spelRonde.setWinnaar(getWinnaar());
                spelRonde.setDeler(getWinnaar());
                spelRonde.setRondeNummer(spelRonde.getRondeNummer()+1);
                spelRonde.startSpeelBeurt();
                eindeSpelRonde = true;              
            }
        }
        if(!eindeSpelRonde) {
            getDeelnemerAanDeBeurt().switchIsAanDeBeurt();
        }
    }


    /**
     * Conroleert of de juiste kleur kaart opgegooid is als er al een kaart
     * opgegooid is.
     * @param speelkaart die gespeeld wordt
     * @return true als het de zelfde kleur is
     */
    public boolean getSpelregelKleurBekennen(Kaart speelkaart) {
        if (getWinnendeKaart()==null) {
            setWinnendeKaart(speelkaart);
            return true;
        }
        if (speelkaart.getKleur() == getWinnendeKaart().getKleur()) {
            return true;
        }
        else {
            for (int i=0;i<getDeelnemerAanDeBeurt().getSpeelHand().getNietGespeeldeKaarten().size();i++){
                if (getWinnendeKaart().getKleur()==getDeelnemerAanDeBeurt().getSpeelHand().getNietGespeeldeKaarten().get(i).getKleur()){
                    return false;
                }
            }
            return true;
        }
    }

    /**
     * Maakt de speelhand leeg van alle deelnemers
     */
    public void geefKaartenTerug(){
        for (int i=0;i<=lijstDeelnemer.size()-1;i++){
            lijstDeelnemer.get(i).setSpeelHand(null);
        }
    }
}

